<script setup lang="ts">

import {useUserStore} from "@/common/user_store.ts";
import {ref, watch, watchEffect} from "vue";

const store = useUserStore();

const name = ref(store.name);
//修改store
watchEffect(() => {
  //方式1：直接修改
  // store.name = name.value;
  //方式2：打补丁（不能删除）
  // store.$patch({
  //   name: name.value,
  // });
  //方式3：全权掌握state
  //path接收一个回调函数，全权掌控state
  store.$patch((state) => {
    state.name = name.value;
  });




})

function reset(){
  store.$reset();//重置store
  name.value = "";//重置ref
}

const email = ref(store.email);
function change() {
  console.log("store state is changing....");
  store.email = email.value;
}

store.$subscribe((mutation, state)=>{
  console.log('watch store change')
  console.log(mutation);
  console.log(state);
  // 每当状态发生变化时，将整个 state 持久化到本地存储。
  localStorage.setItem('state_subscribe', JSON.stringify(state));
});

watchEffect(() => {
  console.log("watch store change");
  localStorage.setItem('state_watch',JSON.stringify(store));
});

</script>

<template>
  <el-card class="mb-4">
    <template #header>定义store</template>

    <h5>选项式</h5>
    <pre v-highlight><code class="javascript">import {defineStore} from "pinia";
import {computed, ref} from "vue";

//store风格1：Setup Store
export const useUserStore = defineStore('user', () => {
    //state 属性
    const count = ref(0);
    //getters
    const doubleCount=computed(() => {
        return count.value*2;
    })
    //actions
    function increment() {
        count.value++;
    }

    return {count,doubleCount, increment};
})</code>
    </pre>
    <h5>组合式</h5>
    <pre v-highlight><code class="javascript">import {defineStore} from "pinia";
import {computed, ref} from "vue";

//store风格1：Setup Store
export const useUserStore = defineStore('user', () => {
    //state 属性
    const count = ref(0);
    //getters
    const doubleCount=computed(() => {
        return count.value*2;
    })
    //actions
    function increment() {
        count.value++;
    }

    return {count,doubleCount, increment};
})</code>
</pre>

  </el-card>
  <el-card class="mb-4">
    <template #header>使用store</template>
    <pre>
const store = useUserStore();
    </pre>
    <p>{{ store.name }}</p>

  </el-card>

  <el-card class="mb-4">
    <template #header>重置 state</template>
    <pre>
const store = useUserStore()
store.$reset()
    </pre>
    <div>
      <p>store name: {{ store.name }}</p>
      <p>model name: {{ name }}</p>
      <el-space size="small">
        <el-input v-model="name" style="width: 240px;height: 30px;" placeholder="请输入" ></el-input>
        <el-button @click="reset" style="height: 30px;">重置</el-button>
      </el-space>

    </div>
  </el-card>

  <el-card class="mb-4">
    <template #header>变更state</template>
    <p>除了用 store.count++ 直接改变 store，你还可以调用 $patch 方法。它允许你用一个 state 的补丁对象在同一时间更改多个属性</p>
    <pre>
store.$patch({
  count: store.count + 1,
  age: 120,
  name: 'DIO',
})
    </pre>

    <p>不过，用这种语法的话，有些变更真的很难实现或者很耗时：任何集合的修改（例如，向数组中添加、移除一个元素或是做 splice 操作）都需要你创建一个新的集合。因此，$patch 方法也接受一个函数来组合这种难以用补丁对象实现的变更</p>
    <pre>
store.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})
    </pre>
    <h4>示例</h4>
    <pre>
//方式1：直接修改
store.name = name.value;
//方式2：打补丁（不能删除）
store.$patch({
   name: name.value,
});
//方式3：全权掌握state
//path接收一个回调函数，全权掌控state
store.$patch((state) => {
  state.name = name.value;
});
</pre>
  </el-card>

  <el-card class="mb-4">
    <template #header>替换 state</template>
    你不能完全替换掉 store 的 state，因为那样会破坏其响应性。但是，你可以 patch 它
    <pre>
// 这实际上并没有替换`$state`
store.$state = { count: 24 }
// 在它内部调用 `$patch()`：
store.$patch({ count: 24 })
    </pre>
    <p>你也可以通过变更 pinia 实例的 state 来设置整个应用的初始 state。这常用于 SSR 中的激活过程。</p>
    <pre>
pinia.state.value = {}
    </pre>
  </el-card>

  <el-card>
    <template #header>订阅 state</template>
    <p>store email: {{store.email}}</p>
    <el-space>
      <el-input style="width: 240px;height: 40px;" v-model="email"></el-input>
      <el-button style="height: 40px;" @click="change">提交</el-button>
    </el-space>
  </el-card>


</template>

<style scoped>

</style>